local ByteArrayInputStream = require('lua.io.ByteArrayInputStream')
local Lexer = require('lua.parser.Lexer')
local StringAndNumberEncryptor = require('lua.encryptor.StringAndNumberEncryptor')
local PrintOutputStream = require('lua.io.PrintOutputStream')
local TokenKind = require('lua.parser.TokenKind')
local LexToken = require('lua.parser.LexToken')

local src = [===============[
print('Hello world!', 323617915)
]===============]

local bis = ByteArrayInputStream:new(src:toByteArray())
local pos = PrintOutputStream:new()
local encryptor = StringAndNumberEncryptor:new(Lexer:new(bis), pos)

--- @private
--- @return string
function LexToken:loadRealData()
	return load('return ' .. self.value)()
end

--- @private
--- @param t LexToken
--- @return string
function string:encrypt(t)
	return self:format(table.concat(tostring(t:loadRealData()):toByteArray(), ', '))
end

encryptor:encrypt(function(t)
	local k = t.kind
	if k == TokenKind.String then
		return ('(string.char(table.unpack({%s})))'):encrypt(t)
	elseif k == TokenKind.Number then
		return ('tonumber(string.char(table.unpack({%s})))'):encrypt(t)
	end
	return t.value
end)

bis:close()
pos:close()